package com.opd.soeghtool;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.constraint.ConstraintLayout;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


public class EnterGameService extends Service {

    private final String TAG = "SOEEGS";

    int panelHeight,panelWidth;
    WindowManager windowManager;
    WindowManager.LayoutParams paramsFloat,paramsQuick,paramsBack;
    GlobalVar mGlobalVar;
    MyBroadcastReceive myBroadcastReceive;

    ConstraintLayout float_layout;
    LinearLayout quickViewLayout,float_back_layout;

    ListView lv_btnlist;
    FuncAdapter funcAdapter;
    ArrayList<Map<String, Object>> listData;
    int Img[] ={R.drawable.btn_a,R.drawable.btn_b,R.drawable.btn_x,R.drawable.btn_y,R.drawable.btn_up,R.drawable.btn_down,R.drawable.btn_left,R.drawable.btn_right,
            R.drawable.l1,R.drawable.r1,R.drawable.l2,R.drawable.r2,R.drawable.btn_s2,R.drawable.btn_s1,R.drawable.btn_s4,R.drawable.btn_s3};

    byte u8DataBuffer[];
    byte g_u8tAttrTable[][];

    boolean bHalfshow = false,bfloatView=false,bIsShowWin = false;
    private static Handler handler;
    private Message message;

    private int floatWindowSize = 100;
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public void onCreate() {
        super.onCreate();
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getRealMetrics(dm);
        mGlobalVar = (GlobalVar)getApplication();
        mGlobalVar.setIsGameServiceRunning(true);

        u8DataBuffer = new byte[Transfer_Con.HID_PACKET_SIZE];
        g_u8tAttrTable = new byte[mGlobalVar.getDeviceMaxButton()][3];
        paramsFloat = new WindowManager.LayoutParams();
        paramsQuick = new WindowManager.LayoutParams();
        paramsBack = new WindowManager.LayoutParams();
        windowManager = (WindowManager) getApplication().getSystemService(Context.WINDOW_SERVICE);
        paramsBack.format =paramsFloat.format = paramsQuick.format = PixelFormat.RGBA_8888;
        //设置flags.不可聚焦及不可使用按钮对悬浮窗进行操控.
        paramsBack.flags =paramsFloat.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        paramsQuick.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            paramsBack.type  =paramsFloat.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            paramsQuick.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            paramsBack.type  =paramsFloat.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
            paramsQuick.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            paramsFloat.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            paramsQuick.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            paramsBack .layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        }
        //设置窗口初始停靠位置.
        paramsFloat.gravity = Gravity.START | Gravity.TOP;
        paramsQuick.gravity = Gravity.START | Gravity.TOP;
        paramsBack.gravity = Gravity.START | Gravity.TOP;
        Log.d(TAG,String.format("wid=%d, hei=%d",dm.widthPixels,dm.heightPixels));
        panelHeight = dm.heightPixels;
        panelWidth = dm.widthPixels;

        if (panelWidth < panelHeight) {
            int a = panelWidth;
            panelWidth = panelHeight;
            panelHeight = a;
            Log.d(TAG, "swap to Landscape Mode");
        }

        floatWindowSize =  dip2px(this,30);

        paramsFloat.width = floatWindowSize;
        paramsFloat.height = floatWindowSize;
        paramsBack.width = floatWindowSize;
        paramsBack.height = floatWindowSize;

        paramsQuick.width = dip2px(this,120);
        paramsQuick.height = dip2px(this,150);
        Log.d(TAG,String.format("wid=%d, hei=%d",paramsFloat.width,paramsFloat.height));

        LayoutInflater inflater = LayoutInflater.from(getApplication());

        //获取浮动窗口视图所在布局.
        float_layout = (ConstraintLayout) inflater.inflate(R.layout.float_layout, null);
        quickViewLayout = (LinearLayout) inflater.inflate(R.layout.quickview_layout, null);
        float_back_layout = (LinearLayout) inflater.inflate(R.layout.game_float_back_layout, null);
        lv_btnlist = (ListView)quickViewLayout.findViewById(R.id.lv_quick_view);
       // Log.d(TAG,tv_qv_cur_game.getText().toString());

        paramsFloat.x =  panelWidth/5;
        paramsFloat.y =  0;
        paramsBack.x = paramsFloat.x + floatWindowSize;
        paramsBack.y =  paramsFloat.y;
        paramsQuick.x = paramsBack.x + floatWindowSize;
        paramsQuick.y = paramsFloat.y;
        windowManager.addView(float_layout, paramsFloat);
        //windowManager.addView(quickViewLayout, paramsQuick);
        bIsShowWin = true;
        myBroadcastReceive = new MyBroadcastReceive();
//注册广播接收,注意：要监听这个系统广播就必须用这种方式来注册，不能再xml中注册，否则不能生效
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.intent.action.CONFIGURATION_CHANGED");
        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        filter.addAction("com.opd.soeghtool.content");
        registerReceiver(myBroadcastReceive,filter);

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Log.i(TAG,"handleMessage");
                if (!bHalfshow) {
                    float_layout.scrollBy(0, floatWindowSize / 2);
                    windowManager.updateViewLayout(float_layout, paramsFloat);
                    bHalfshow = true;
                }

                    if (bfloatView && (quickViewLayout != null)) {
                        windowManager.removeView(quickViewLayout);
                        windowManager.removeView(float_back_layout);
                        bfloatView = false;
                    }

            }
        };

        float_layout.setOnTouchListener(new View.OnTouchListener() {
            int prevX=0,prevY=0;
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int pos_x,pos_y;
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.i(TAG,"ACTION_DOWN");
                        prevX = (int)event.getRawX();
                        prevY = (int)event.getRawY();
                        handler.removeMessages(0);
                        if (bHalfshow) {
                                float_layout.scrollBy(0, -floatWindowSize / 2);
                            //params.width = 50;
                            windowManager.updateViewLayout(float_layout, paramsFloat);
                            bHalfshow = false;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        /*
                        if((Math.abs(prevX-(int)event.getRawX())>10)||(Math.abs(prevY-(int)event.getRawY())>10)) {
                            pos_x = (int) event.getRawX() - mImgBtnSize;
                            pos_y = (int) event.getRawY() - mImgBtnSize;
                            //Log.i(TAG, String.format("ACTION_MOVE x=%d, y=%d", pos_x, pos_y));
                            v.setX(pos_x);
                            v.setY(pos_y);
                        }*/
                        break;
                    case MotionEvent.ACTION_UP:

                        if(!bfloatView)
                        {
                            windowManager.addView(quickViewLayout, paramsQuick);
                            windowManager.addView(float_back_layout, paramsBack);
                            bfloatView = true;
                        }
                        else
                        {
                            windowManager.removeView(quickViewLayout);
                            windowManager.removeView(float_back_layout);
                            bfloatView = false;
                        }

                        if (!bHalfshow) {
                            Log.i(TAG,"!bHalfshow");
                                message = handler.obtainMessage();
                                message.what = 0;
                                message.arg1 = (int) paramsFloat.x;
                                message.arg2 = (int) paramsFloat.y;
                                /*手指抬起5s内没有操作的话，让图标变小*/
                                handler.sendMessageDelayed(message, 5000);
                        }
                        break;
                }
                return false;
            }
        });

        float_back_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.setClass(getBaseContext(), MainActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                getApplication().startActivity(intent);
            }
        });
        //******************
        /*
        g_u8tAttrTable[0][0] =0x01;
        g_u8tAttrTable[1][0] =0x01;
        g_u8tAttrTable[2][0] =0x01;
        g_u8tAttrTable[3][0] =0x01;
        g_u8tAttrTable[4][0] =0x01;
        g_u8tAttrTable[5][0] =0x01;
        */

            listData = new ArrayList<Map<String, Object>>();
            for (int a = 0; a < 3; a++) {
                if (mGlobalVar.tranGet_Value(Transfer_Con.HID_CMD_GET_KEY_ATTR, a, 0, u8DataBuffer)) {
                    for (int k = 0; k < mGlobalVar.getDeviceMaxButton(); k++) {
                        g_u8tAttrTable[k][a] = u8DataBuffer[16 + k];
                    }
                }
            }

            for (int k = 0; k < mGlobalVar.getDeviceMaxButton(); k++) {

                if(g_u8tAttrTable[k][0]!=0) {   // have function
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("btn",k );
                    map.put("func",(int)g_u8tAttrTable[k][0] );
                    if ((g_u8tAttrTable[k][0] & 0x80) == 0x80) {    // on
                        map.put("sw",true );
                    } else {
                        map.put("sw",false );
                    }
                    //Log.d(TAG,"attr 0: "+String.format("0x%x",g_u8tAttrTable[k][0] ));
                    listData.add(map);

                }
            }
            // Log.d(TAG,"list size="+String.valueOf(listData.size()));
            funcAdapter = new FuncAdapter(EnterGameService.this);
            lv_btnlist.setAdapter(funcAdapter);
            lv_btnlist.setOnScrollListener(new AbsListView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    switch (scrollState){
                        case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                            message = handler.obtainMessage();
                            message.what = 0;
                            message.arg1 = (int) paramsFloat.x;
                            message.arg2 = (int) paramsFloat.y;
                            handler.sendMessageDelayed(message, 5000);
                            break;

                        case SCROLL_STATE_TOUCH_SCROLL:
                            handler.removeMessages(0);
                            Log.d(TAG,"List tv setOnScrollListener: ");
                            break;

                        case SCROLL_STATE_FLING:
                            break;
                    }


                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    //Toast.makeText(MainService.this,""+firstVisibleItem,Toast.LENGTH_SHORT).show();
                }
            });

        if(mGlobalVar.getIsEnterGameNeedGuide()) {
            // User Guide
            if(!bfloatView)
            {
                windowManager.addView(quickViewLayout, paramsQuick);
                windowManager.addView(float_back_layout, paramsBack);
                bfloatView = true;
            }
            mGlobalVar.setIsEnterGameGuide(true);
            Intent intent = new Intent(EnterGameService.this, UserGuideService.class);
            startService(intent);
        }
        else {
            message = handler.obtainMessage();
            message.what = 0;
            message.arg1 = (int) paramsFloat.x;
            message.arg2 = (int) paramsFloat.y;
            handler.sendMessageDelayed(message, 5000);
        }

    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy()
    {
        Log.d(TAG,"onDestroy");
        handler.removeMessages(0);
        unregisterReceiver(myBroadcastReceive);
        if(bfloatView) {
            windowManager.removeView(quickViewLayout);
            windowManager.removeView(float_back_layout);
        }
        windowManager.removeView(float_layout);
        mGlobalVar.setIsGameServiceRunning(false);
        super.onDestroy();
    }

    public void refleshQuickView()
    {

    }

    public static int dip2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

    public void showWin()
    {
        if(!bIsShowWin) {
            if (!mGlobalVar.getIsSettingServiceRunning()) {
                windowManager.addView(float_layout, paramsFloat);
                bIsShowWin = true;
                if (bHalfshow) {
                    float_layout.scrollBy(0, -floatWindowSize / 2);
                    windowManager.updateViewLayout(float_layout, paramsFloat);
                    bHalfshow = false;
                }
                message = handler.obtainMessage();
                message.what = 0;
                message.arg1 = (int) paramsFloat.x;
                message.arg2 = (int) paramsFloat.y;
                handler.sendMessageDelayed(message, 5000);
            }
        }
    }

    public void hideWin()
    {
        if(bIsShowWin) {
            handler.removeMessages(0);
            if (bfloatView) {
                windowManager.removeView(quickViewLayout);
                windowManager.removeView(float_back_layout);
                bfloatView = false;
            }
            windowManager.removeView(float_layout);
            bIsShowWin = false;
        }
    }

    class MyBroadcastReceive extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub

            Configuration mConfiguration = context.getResources().getConfiguration(); //获取设置的配置信息
            int ori = mConfiguration.orientation; //获取屏幕方向
            if (ori == Configuration.ORIENTATION_LANDSCAPE) {
                //横屏
                Log.d(TAG,"横屏 "+String.valueOf(ori));
                showWin();
            } else if (ori == Configuration.ORIENTATION_PORTRAIT) {
                //竖屏
                Log.d(TAG,"竖屏 "+String.valueOf(ori));
                hideWin();
                //stopSelf();

            }
            String action=intent.getAction();
            if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))
            {
                mGlobalVar.setbIsUsbConnect(false);
                mGlobalVar.setbIsTransferMode(false);
                mGlobalVar.myUsbDevice = null;
                mGlobalVar.myInterface = null;
                mGlobalVar.epOut = null;
                mGlobalVar.epIn = null;
                stopSelf();
            }

            if("com.opd.soeghtool.content".equals(action))
            {
                String name = intent.getStringExtra("Guide");
                if(name.equals("Game"))
                {
                    SharedPreferences.Editor editor = getSharedPreferences(Transfer_Con.SAVENAME, MODE_PRIVATE).edit();
                    editor.putBoolean("GameGuide", mGlobalVar.getIsEnterGameNeedGuide());
                    editor.apply();
                    message = handler.obtainMessage();
                    message.what = 0;
                    message.arg1 = (int) paramsFloat.x;
                    message.arg2 = (int) paramsFloat.y;
                    handler.sendMessageDelayed(message, 5000);
                }
            }

        }
    }

    class FuncAdapter extends BaseAdapter {
        private Context context = null;

        private FuncAdapter(Context context) {
            this.context = context;
        }

        @Override
        public int getCount() {
            return listData.size();
        }

        @Override
        public Object getItem(int position) {
            return listData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder mHolder;
            final int pos = position;
            if (convertView == null) {
                mHolder = new ViewHolder();
                LayoutInflater inflater = LayoutInflater.from(context);
                convertView = inflater.inflate(R.layout.listview_quick_view, null, true);

                mHolder.iv_lv_btnimg = (ImageView) convertView.findViewById(R.id.iv_qv_btn);
                mHolder.sw_lv_function_onoff = (Switch) convertView.findViewById(R.id.sw_qv_btn);
                mHolder.tv_lv_function = (TextView) convertView.findViewById(R.id.tv_qv_btn);

                convertView.setTag(mHolder);
            } else {
                mHolder = (ViewHolder) convertView.getTag();
            }
            mHolder.iv_lv_btnimg.setImageResource(Img[(int)listData.get(position).get("btn")]);
            //Log.d(TAG,"List sw: "+String.valueOf((boolean)listData.get(position).get("sw")));
            mHolder.sw_lv_function_onoff.setChecked((boolean)listData.get(position).get("sw"));
            //Log.d(TAG,"List Btn: "+String.valueOf((int)listData.get(position).get("btn")));
            String strButtonFunctionName[] = getResources().getStringArray(R.array.StringButtonFunction);
            switch ((int)listData.get(position).get("func")&Transfer_Con.ATTR_MASK)
            {
                case Transfer_Con.bSkillWithDirect:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[0]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[0]);
                    break;
                case Transfer_Con.bFPSPullGunDown:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[1]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[1]);
                    break;
                case Transfer_Con.ATTR_MACRO:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[2]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[2]);
                    break;
                case Transfer_Con.bWZRYCancelConjure:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[3]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[3]);
                    break;
                case Transfer_Con.bSwipe:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[4]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[4]);
                    break;
                case Transfer_Con.bCancelAutoEvent:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[6]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[6]);
                    break;
                case Transfer_Con.ATTR_MACRO_ADV:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[5]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[5]);
                break;
                default:
                    mHolder.tv_lv_function.setText(strButtonFunctionName[7]);
                    //mHolder.tv_lv_function.setText(Transfer_Con.tFunctionName[7]);
                    break;
            }

            mHolder.tv_lv_function.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handler.removeMessages(0);
                    message = handler.obtainMessage();
                    message.what = 0;
                    message.arg1 = (int) paramsFloat.x;
                    message.arg2 = (int) paramsFloat.y;
                    Log.d(TAG,"List tv setOnClickListener: ");
                    handler.sendMessageDelayed(message, 5000);
                }
            });

            mHolder.sw_lv_function_onoff.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    handler.removeMessages(0);
                    final int index = (int)listData.get(pos).get("btn");
                    //mGlobalVar.tranGet_Value(Transfer_Con.HID_CMD_GET_AEV_ONOFF,index,0,u8DataBuffer);
                    int data;
                    //Log.d(TAG,"data1: "+String.format("0x%x",data));
                    if(((int)g_u8tAttrTable[index][0]&0x80)==0x80)
                        data = 0;
                    else
                        data = 1;
                    //mGlobalVar.IntToByte((int)data,u8DataBuffer,0);
                    //Log.d(TAG,"data2: "+String.format("0x%x",data));
                    mGlobalVar.tranSet_Value(Transfer_Con.HID_CMD_SET_AEV_ONOFF,data,index);

                    for (int a = 0; a < 3; a++) {
                        if (mGlobalVar.tranGet_Value(Transfer_Con.HID_CMD_GET_KEY_ATTR, a, 0, u8DataBuffer)) {
                            for (int k = 0; k < mGlobalVar.getDeviceMaxButton(); k++) {
                                g_u8tAttrTable[k][a] = u8DataBuffer[16 + k];
                            }
                        }
                    }
                    listData.clear();
                    for (int k = 0; k < mGlobalVar.getDeviceMaxButton(); k++) {

                        if(g_u8tAttrTable[k][0]!=0) {   // have function
                            Map<String, Object> map = new HashMap<String, Object>();
                            map.put("btn",k );
                            map.put("func",(int)g_u8tAttrTable[k][0] );
                            if ((g_u8tAttrTable[k][0] & 0x80) == 0x80) {    // on
                                map.put("sw",true );
                            } else {
                                map.put("sw",false );
                            }
                            listData.add(map);
                        }
                    }
                    message = handler.obtainMessage();
                    message.what = 0;
                    message.arg1 = (int) paramsFloat.x;
                    message.arg2 = (int) paramsFloat.y;
                    handler.sendMessageDelayed(message, 5000);
                }

            });
            //Log.d(TAG,"Btn Act: "+mHolder.tv_lv_function.getText());
            return convertView;
            //mHolder.btn_lv_launch.setVisibility(View.VISIBLE);
        }


        class ViewHolder {
            private ImageView iv_lv_btnimg;
            private Switch sw_lv_function_onoff;
            private TextView tv_lv_function;
        }
    }
}
